!(function () {
  function EchartsLayer(viewer) {
    this._viewer = viewer;
    registerMap(this);
    createChart(this);
    resize(this);
  }

  Object.defineProperties(EchartsLayer.prototype, {
    chart: {
      get: function () {
        return this._chart;
      }
    }
  })

  function registerMap(layer) {
    if (!Cesium.defined(echarts)) {
      throw new Cesium.DeveloperError("echarts is undefined.");
    }
    echarts.registerCoordinateSystem("GLMap", getCoordinateSystem(layer._viewer)),
      echarts.registerAction({
        type: "GLMapRoam",
        event: "GLMapRoam",
        update: "updateLayout"
      }, function (t, e) {
      }),
      echarts.extendComponentModel({
        type: "GLMap",
        defaultOption: { roam: !1 }
      });
    echarts.extendComponentView({
      type: "GLMap",
      init: function (t, e) {
        this.api = e;
        layer._viewer.scene.postRender.addEventListener(this.moveHandler, this)
      },
      moveHandler: function (t, e) {
        this.api.dispatchAction({
          type: "GLMapRoam"
        });
      },
      render: function (t, e, i) {
      },
      dispose: function (t) {
        layer._viewer.scene.postRender.removeEventListener(this.moveHandler, this)
      }
    });
  }

  function createChart(layer) {
    var scene = layer._viewer.scene;
    scene.canvas.setAttribute("tabIndex", 0);
    var ele = document.createElement('div');
    ele.style.position = "absolute";
    ele.style.top = "0px";
    ele.style.left = "0px";
    ele.style.width = scene.canvas.width + "px";
    ele.style.height = scene.canvas.height + "px";
    ele.style.pointerEvents = "none";
    ele.setAttribute("id", "echarts");
    ele.setAttribute("class", "echartMap");
    layer._viewer.container.appendChild(ele);
    layer._echartsContainer = ele;
    layer._chart = echarts.init(ele);
  }

  function resize(layer) {
    window.onresize = function () {
      var scene = layer._viewer.scene;
      layer._echartsContainer.style.width = scene.canvas.style.width + "px";
      layer._echartsContainer.style.height = scene.canvas.style.height + "px";
      layer._chart.resize();
    }
  }

  EchartsLayer.prototype.isDestroyed = function () {
    return false;
  };

  EchartsLayer.prototype.destroy = function () {
    if (this._echartsContainer) {
      this._viewer.container.removeChild(this._echartsContainer);
      this._echartsContainer = undefined;
    }
    if (this._chart) {
      this._chart.dispose();
      this._chart = undefined;
    }
    Cesium.destroyObject(this);
  }

  function getCoordinateSystem(viewer) {
    function GLMapCoordSys(api) {
      this.dimensions = ['lng', 'lat'];
      this._mapOffset = [0, 0];
      this._api = api;
      this._viewer = viewer;
      this._occluder = new Cesium.EllipsoidalOccluder(this._viewer.scene.globe.ellipsoid, this._viewer.scene.camera.position);
    }

    GLMapCoordSys.prototype.dimensions = ['lng', 'lat']

    GLMapCoordSys.prototype.setMapOffset = function (mapOffset) {
      this._mapOffset = mapOffset;
    };

    GLMapCoordSys.prototype.dataToPoint = function (data) {
      var e = [0, 0],
        i = Cesium.Cartesian3.fromDegrees(data[0], data[1]);
      if (!i) return e;
      this._occluder.cameraPosition = this._viewer.scene.camera.position;
      if (!this._occluder.isPointVisible(i)) {
        return [];
      };
      var n = viewer.scene.cartesianToCanvasCoordinates(i);
      if (!n) return e;
      return (Cesium.Cartesian3.angleBetween(viewer.scene.camera.position, i) < Cesium.Math.toRadians(75))
        ? [n.x - this._mapOffset[0], n.y - this._mapOffset[1]] : e;
    }

    GLMapCoordSys.prototype.pointToData = function (pt) {
      var mapOffset = this._mapOffset;
      var cart = viewer.scene.pickPosition(
        new Cartesian2(pt[0] + mapOffset[0], pt[1] + mapOffset[1]), new Cesium.Cartesian3()
      );
      var carto = Cesium.Cartographic.fromCartesian(cart);
      return [Cesium.Math.toDegrees(carto.longitude), Cesium.Math.toDegrees(carto.latitude)];
    }

    GLMapCoordSys.prototype.getViewRect = function () {
      var api = this._api
      return new echarts.graphic.BoundingRect(0, 0, api.getWidth(), api.getHeight())
    }

    GLMapCoordSys.prototype.getRoamTransform = function () {
      return echarts.matrix.create();
    }

    GLMapCoordSys.dimensions = GLMapCoordSys.prototype.dimensions

    GLMapCoordSys.create = function (ecModel, api) {
      var coordSys;
      ecModel.eachComponent('GLMap', function (GLMapModel) {
        coordSys = new GLMapCoordSys(api);
        coordSys.setMapOffset(GLMapModel.__mapOffset || [0, 0]);
        GLMapModel.coordinateSystem = coordSys;
      })
      ecModel.eachSeries(function (seriesModel) {
        if (seriesModel.get('coordinateSystem') === 'GLMap') {
          seriesModel.coordinateSystem = coordSys;
        }
      })
    }
    return GLMapCoordSys;
  }

  window.EchartsLayer = EchartsLayer;
})();